﻿using System;
using System.Net;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using System.Collections.Generic;

namespace SimpleServiceBus.Tests
{
    [TestFixture]
    public class EventRecorderTestFixture
    {
        [Test]
        public void Recorder_Will_Bind_To_Events_Then_Unbind_From_Events_When_Disposed()
        {
            var source = new TestEventSource();
            Assert.IsFalse(source.IsSimpleEventHandled);
            Assert.IsFalse(source.IsEventWithCustomArgsHandled);

            using (new EventRecorder(source))
            {
                Assert.IsTrue(source.IsSimpleEventHandled);
                Assert.IsTrue(source.IsEventWithCustomArgsHandled);
            }

            Assert.IsFalse(source.IsSimpleEventHandled);
            Assert.IsFalse(source.IsEventWithCustomArgsHandled);
        }

        [Test]
        public void Recorder_Will_Fire_Aggregation_Event()
        {
            var source = new TestEventSource();
            using (var recorder = new EventRecorder(source))
            {
                using (var recorderRecorder = new EventRecorder(recorder))
                {
                    source.FireSimpleEvent();
                    source.FireSimpleEvent();
                    source.FireEventWithCustomArgs("MyTestText");
                    source.FireSimpleEvent();
                    source.FireEventWithCustomArgs("NewTestText");

                    Assert.That(recorderRecorder.EventHistory.Length, Is.EqualTo(recorder.EventHistory.Length));
                    Assert.That(recorderRecorder.GetInvocationsFor("EventRecorded").Length,
                                Is.EqualTo(recorder.EventHistory.Length));
                }
            }
        }

        [Test]
        public void Recorder_Will_Record_Events()
        {
            var source = new TestEventSource();

            using (var recorder = new EventRecorder(source))
            {
                source.FireSimpleEvent();
                source.FireSimpleEvent();
                source.FireEventWithCustomArgs("MyTestText");
                source.FireSimpleEvent();
                source.FireEventWithCustomArgs("NewTestText");

                Assert.That(recorder.EventHistory.Length, Is.EqualTo(5));

                Assert.That(((TestEventArgs) recorder.EventHistory[2].Args).LoveMe, Is.EqualTo("MyTestText"));
                Assert.That(((TestEventArgs) recorder.EventHistory[4].Args).LoveMe, Is.EqualTo("NewTestText"));

                Assert.That(recorder.GetInvocationsFor("SimpleEvent").Length, Is.EqualTo(3));
                Assert.That(recorder.GetInvocationsFor("EventWithCustomargs").Length, Is.EqualTo(2));
            }
        }
    }

    public class TestEventSource
    {
        public bool IsSimpleEventHandled
        {
            get { return SimpleEvent != null; }
        }

        public bool IsEventWithCustomArgsHandled
        {
            get { return EventWithCustomArgs != null; }
        }

        public event EventHandler SimpleEvent;
        public event EventHandler<TestEventArgs> EventWithCustomArgs;

        public void FireSimpleEvent()
        {
            if (SimpleEvent != null)
                SimpleEvent(this, new EventArgs());
        }

        public void FireEventWithCustomArgs(string testText)
        {
            if (EventWithCustomArgs != null)
                EventWithCustomArgs(this, new TestEventArgs {LoveMe = testText});
        }
       
    }

    public class TestEventArgs : EventArgs
    {
        public string LoveMe { get; set; }
    }


}